﻿using System;
//using System.Threading;
using System.Timers;
using System.Threading;
using System.Collections.Generic;
using System.Collections;
//using System.ComponentModel;
//using System.Data;
using System.Drawing;
//using System.Linq;
//using System.Text;
using System.Windows.Forms;
using System.IO;

namespace PCANLINDemo
{
    public partial class Form1 : Form
    {

        private enum LOGType
        {
            INFO,
            WARNING,
            ERROR
        };
        private enum PCANLINMSGType
        {
            SERIAL,
            CAN,
            LIN,
            Module,
            None
        };

        private class LOGDEBUG
        {
            private string logFile;
            private string logTime;
            private FileInfo fLog;
            private Boolean lockFlag;

            public LOGDEBUG()
            {
                logTime = DateTime.Now.ToString("_yyMMdd");
                this.logFile = "log" + logTime + ".log";
                fLog = new FileInfo(this.logFile);
                this.lockFlag = false;
            }

            private string getNowString()
            {
                string s;
                s = DateTime.Now.ToString("yy-MM-dd：hh.mm.ss.fff: --");
                return s;
            }

            public Boolean appendLogText(string text, LOGType logType = LOGType.INFO)
            {
                string prefix;
                string finalString;

                switch (logType)
                {
                    case LOGType.ERROR: prefix = "[ERROR] "; break;
                    case LOGType.INFO: prefix = "[INFO] "; break;
                    case LOGType.WARNING: prefix = "[WARNING] "; break;
                    default:
                        prefix = "[ERROR]"; break;

                }

                if (this.lockFlag ) {
                    return false;
                }

                this.lockFlag = true;

                finalString = this.getNowString() + prefix + text;
                StreamWriter sw = fLog.AppendText();
                try
                {
                    if (!fLog.Exists)
                    {
                        fLog.Create().Close();
                    }
                    sw.WriteLine(finalString);
                    return true;
                }
                catch (Exception err)
                {
                    //only could write it down in the status bar.
                    return false;
                }
                finally
                {
                    sw.Flush();
                    sw.Close();
                    this.lockFlag = false;
                }
            }

        }
        
        #region members declaration of class Form1
        private static LOGDEBUG myLog = new LOGDEBUG();
        private volatile byte[] msgLIN;
        private volatile byte[] msgTmp;
        private string port;
        //private Boolean LINDataReadyFlag;
        //private volatile Boolean msgFinishedFlag;
        private iSerial serialInstance;

        #endregion 

        public Form1()
        {
            InitializeComponent();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            this.serialInstance.closePort();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.port = "COM10";
            this.serialInstance = new iSerial(this.port);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            serialInstance.openPort();
        }

        //this class defines the LIN class.
        //memebers:
        //byte[] msgLINReceived
        //byte[] msgLINDefault
        //byte[] msgLINSend
        //byte header
        private class LINManager {
            private byte[] msgLINReceived;
            private byte[] msgLINDefault;
            private byte[] msgLINSend;
            private byte header;
            public Boolean LINReceivedCompleteFlag;
            private int LINRecCount;

            public LINManager() {
                this.msgLINDefault = new byte[8];
                this.msgLINReceived = new byte[8];
                this.msgLINSend = new byte[8];
                this.LINReceivedCompleteFlag = true;
                LINRecCount = 0;
            }

            public void receiveLINMsgByByte(byte oneByteLIN) {
                this.msgLINReceived[LINRecCount] = oneByteLIN;
                this.LINRecCount += 1;
                if (this.LINRecCount > 8) {
                    this.LINRecCount = 0;
                }
            }

            public void setHeader(byte newHeader) {
                this.header = newHeader;            
            }

            public void setDefault(byte[] newDefault) {
                //int i = 1;
                this.setMsg(newDefault, this.msgLINDefault);
                this.msgLINDefault[0] = this.header;
            }

            private void setSend(byte[] newSend) {
                this.setMsg(newSend, this.msgLINSend);
                this.msgLINSend[0] = this.header;
            }

            private void setMsg(byte[] newMsg, byte[] oldMsg) {
                for (int i = 1; i < 9; i++) {
                    oldMsg[i] = newMsg[i - 1];
                }
            }
        }

        //this class defines the current received PCANLIN message.
        //it means, the current parsing complete PCANLIN message.
        //
        private class PCANLINReceiveMessage {
            public Boolean firstFlag;
            public Boolean MessageCompleteFlag;
            public Boolean oneCompleteLINFlag;
            public Boolean parameterFinishFlag;
            public Boolean stxCompleteFlag;
            public Boolean sqcCompleteFlag;
            public Boolean checkSumFlag;
            //public DictionaryEntry PCANLINMessage;
            //private ArrayList PCANLINMessage;
            public string tmpStr;

         
            public byte stx;
            public byte sequenceCode;
            public ArrayList debugArray;
            public ArrayList debugArray2;
            public ArrayList debugArray3;
            public ArrayList debugArrayRawdata;

            public int frameLength;
            public int AR;
            public int sequenceNumber;
            public volatile int currentParaPos;
            public int currentPCANPos;

           // public List<byte> tmpBuffer;
            public List<byte> parameters;
            //public byte checkSum;
            public PCANLINMSGType msgType;

            private void initPCANLINMessage(){
                this.MessageCompleteFlag = true;
                this.parameters  = new List<byte>();
                //this.tmpBuffer = new List<byte>();
                this.oneCompleteLINFlag = false;
                this.msgType = PCANLINMSGType.None;
                this.debugArray = new ArrayList();
                this.debugArray2 = new ArrayList();
                this.debugArray3 = new ArrayList();
                this.debugArrayRawdata = new ArrayList();

                firstFlag = true;
                parameterFinishFlag = true;
                stxCompleteFlag = false;
                sqcCompleteFlag = false;
                currentParaPos = 0;
                currentPCANPos = 0;
                frameLength = 0;
                checkSumFlag = false;
                tmpStr = "";
            }

            public PCANLINReceiveMessage() {
                this.initPCANLINMessage();
                //this.tmpBuffer = new List<byte>();
            }

            public void analyzePCANLINMessageByByte(byte s)
            {   // this is for debug
                if (this.tmpStr.Length > 30) {
                    this.debugArray3.Add(this.tmpStr);
                    this.tmpStr = "";
                }
                this.tmpStr = this.tmpStr + s.ToString("X2");
                //store the tmpBuffer for debug.
                //this.tmpBuffer.Insert(this.currentPCANPos, s);
                if (this.currentParaPos > this.frameLength)
                {
                    //this means a new PCANLINFrame reached.
                    //this.parameters.Insert(this.currentPraraPos, (byte)this.currentPraraPos);
                    //this.parameters.Insert(this.currentPraraPos + 1, (byte)this.frameLength);

                    //this.debugArray4.Add(this.ToString());
                    this.stxCompleteFlag = false;
                    this.sqcCompleteFlag = false;
                    this.MessageCompleteFlag = true;


                    if (this.checkSum())
                    {

                        if (this.AR == 1)
                        {
                            if (this.sequenceNumber == 2)
                            {
                                this.msgType = PCANLINMSGType.LIN;
                                this.oneCompleteLINFlag = true;
                            }
                        }
                    }
                    else
                    {

                    }
                    //this.currentParaPos = 0;
                    this.parameters.Clear();
                }
                if (!this.stxCompleteFlag)
                {
                    if (s != 0x02) {
                        //if the start of transfer byte not correct, we discard and wait until a valid one come.
                        return;
                    }
                    this.firstFlag = false;
                    this.MessageCompleteFlag = false;
                    this.parameterFinishFlag = false;
                    this.stx = s;
                    this.currentParaPos = 0;
                    //this.currentPCANPos = 1;
                    this.stxCompleteFlag = true;
                }
                else
                {
                    if (!this.sqcCompleteFlag)
                    {
                        this.sequenceCode = s;
                        this.AR = s >> 7;
                        this.sequenceNumber = (s & 0x70) >> 4;
                        this.frameLength = s & 0xF;
                        this.currentParaPos = 0;
                        //this.currentPCANPos = 2;
                        this.sqcCompleteFlag = true;
                    }
                    else
                    {
                        //continue from here.
                        this.parameters.Insert(this.currentParaPos, s);
                        //this.parameters.TrimExcess();
                        if (this.currentParaPos == this.frameLength )
                        {
                            //this.debugArray2.Add(this.currentParaPos);
                            if (this.currentParaPos == 9) {
                                this.debugArray.Add(this.parameters);
                                //string testStr;
                            }
                        }
                        this.currentParaPos += 1;
                    }
                }
            }

            private Boolean checkSum(){
                byte tmpResult;

                tmpResult = this.sequenceCode;

                for (int i = 0; i < this.parameters.Count - 1; i++) {
                    tmpResult ^= this.parameters[i];
                }

                if (tmpResult == this.parameters[this.parameters.Count - 1])
                {
                    return true;
                }
                else {
                    return false;
                }
            }

            public override string ToString()
            {
                string finalStr;
                finalStr = "";

                finalStr += this.stx.ToString("X2");
                finalStr += this.sequenceCode.ToString("X2");
                //for (int i = 0; i < this.parameters.Count; i++) {
                foreach (byte s in this.parameters) {
                    finalStr += s.ToString("X2");
                }
                //for (int i = 0; i < this.frameLength + 1; i++)
                //{
                //    finalStr += this.parameters[i].ToString("X2");
                //}
                return finalStr;
            }
        }

        private class PCANLINSendMessage{
            public Boolean msgQueuedFlag;
            public byte stx;
            public byte sequenceCode;
            public byte controlCode;
            public byte[] parameters;
            public byte checkSum;
            public PCANLINSendMessage() { 
                this.stx = 0x02;
                this.msgQueuedFlag = false;
            }
        }

        private class iSerial {
            private System.IO.Ports.SerialPort mySerial;

            ////disabled for dataReceived Trail
            private System.Timers.Timer ms5Timer;
            private PCANLINReceiveMessage myLINReceiveMessage;
            private PCANLINSendMessage myLINSendMessage;
            public long LINMsgCount;
            //private System.Threading.Timer ms5Timer;

            public iSerial(string portName) {
                mySerial = new System.IO.Ports.SerialPort();
                mySerial.PortName = portName;
                mySerial.BaudRate = 38400;
                mySerial.DataBits = 8;
                mySerial.Parity = System.IO.Ports.Parity.None;
                mySerial.StopBits = System.IO.Ports.StopBits.One;
                mySerial.Handshake = System.IO.Ports.Handshake.None;
                mySerial.ReadBufferSize = 800;
                //mySerial.DiscardNull = true;
                //add this one for dataReceive event trail.
                //mySerial.ReceivedBytesThreshold = 20;
                LINMsgCount = 0;
                myLINReceiveMessage = new PCANLINReceiveMessage();
                myLINSendMessage = new PCANLINSendMessage();

                ms5Timer = new System.Timers.Timer();
                //ms5Timer = new System.Threading.Timer();
                ms5Timer.Interval = 30;
                //MessageBox.Show("Timer Interval " + ms5Timer.Interval.ToString());
                ms5Timer.Elapsed += new ElapsedEventHandler(TimerEvent);
            }

            public Boolean openPort()
            {
                try
                {
                    //myLog.appendLogText("trying to open serial port: " + this.mySerial.PortName);
                    ms5Timer.Enabled = true;
                    this.mySerial.Open();
                    ////disabled for dataReceived trail.
                    //ms5Timer.AutoReset = true;
                    //ms5Timer.Enabled = true;

                }
                catch (Exception err)
                {
                    //write down traces.
                   // myLog.appendLogText("open serial port failed: [" + err.Message + "]");
                    return false;
                }
                myLog.appendLogText("serial port opened.");
                return true;

            }
            public Boolean closePort()
            {
                try
                {
                    //myLog.appendLogText("trying to close serial port: " + this.mySerial.PortName);

                    ////disabled for dataReceived trail

                    this.ms5Timer.Stop();
                    //this.ms5Timer.Enabled = false;
                    this.ms5Timer.Close();
                    this.mySerial.Close();
                    //int i = 0;
                    //debug use only
                    myLog.appendLogText("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$debugArray");
                    foreach (List<byte> lb in myLINReceiveMessage.debugArray) {
                        myLog.appendLogText("Length " + lb.Count.ToString());
                        foreach (byte ss in lb) {
                            myLog.appendLogText(ss.ToString("X2"));
                        }
                    }
                    myLog.appendLogText("################################debugArray2");
                    //foreach (byte[] by in myLINReceiveMessage.debugArray2)
                    //{
                    //    myLog.appendLogText("Length " + by.Length);
                    //    foreach (byte sss in by)
                    //    {
                    //        myLog.appendLogText(sss.ToString("X2"));
                    //    }
                    //}
                    foreach (long iii in myLINReceiveMessage.debugArray2) {
                        myLog.appendLogText(iii.ToString());
                    }
                    myLog.appendLogText("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@debugArray3");

                    foreach (string s in myLINReceiveMessage.debugArray3)
                    {
                        myLog.appendLogText(s);
                    }

                    //myLog.appendLogText("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^debugArray4");
                    //foreach (byte[] by in myLINReceiveMessage.debugArrayRawdata)
                    //{
                    //    myLog.appendLogText("Length " + by.Length);
                    //    foreach (byte sss in by)
                    //    {
                    //        myLog.appendLogText(sss.ToString("X2"));
                    //    }
                    //}

                }
                catch (Exception err)
                {
                    myLog.appendLogText("close serial port failed: [" + err.Message + "]");
                    return false;
                }
                myLog.appendLogText("serial port closed");
                return true;
            }

            private void TimerEvent(object source, ElapsedEventArgs e)
            {
                //string strNow;
                //string strTmp;
                //byte receiveData;
                //string strFile = ""; ;
                //return;

                myLINReceiveMessage.debugArray2.Add(e.SignalTime.Ticks / 10000);
                if (false)
                //if (mySerial.IsOpen)
                {
                    int tmpLength = 0;
                    
                    tmpLength = Convert.ToInt32(mySerial.BytesToRead);
                    #region problem found and solve
                    //continue from here.
                        // here i realize a problem i didn't even though about before.
                        // the serial data is a stream, but per my original solutions. 
                        // after i get the first complete message, i discard the last several bytes, which are the headers of next frame.
                        // it means, in this case, i interrupt the receive stream. then all the followings are not correct.
                        // now i need to figure out a way how to get solve the problem above.
                        // the solution would be:
                        // after i get the complete frame, there is a independent byte array for saving the last several bytes.
                        // every 5 ms, i need to check the first byte of this independent byte array, if it is 0x02, i need to take this array into data parsing.
                        // and build the received PCANLIN frame with data in this byte array.
                        //
#endregion

                    //if (tmpLength > 0)
                    //{
                        byte[] tmpByteArray = new byte[tmpLength];
                        //mySerial.ReadByte
                        try
                        {
                            int count = mySerial.Read(tmpByteArray, 0, tmpByteArray.Length);
                            //myLINReceiveMessage.debugArray2.Add(tmpByteArray);

 
                            myLINReceiveMessage.oneCompleteLINFlag = false;

                            parseRawData(tmpByteArray,1);

                            if (myLINReceiveMessage.oneCompleteLINFlag)
                            {
                                LINMsgCount += 1;
                                myLog.appendLogText(LINMsgCount.ToString() + " " + myLINReceiveMessage.ToString());
                                //we need to check the send msg if we need to send a msg.
                                if (myLINSendMessage.msgQueuedFlag)
                                {
                                    //next work to do is to execute the send command.
                                    
                                }
                            }
                        }
                        catch (Exception err)
                        {
                            //myLINReceiveMessage.firstFlag = true;
                            myLog.appendLogText("##########################EXCEPTION HAPPENED######################");
                            myLINReceiveMessage.firstFlag = true;
                            myLINReceiveMessage.MessageCompleteFlag = true;
                            myLINReceiveMessage.parameterFinishFlag = true;
                            //myLog.appendLogText("BytesToRead: " + tmpLength);
                            //myLog.appendLogText("tmpByteArray length " + tmpByteArray.Length.ToString());
                            //myLog.appendLogText("currentparapos " + myLINReceiveMessage.currentPraraPos.ToString());
                            //myLog.appendLogText("para length " + myLINReceiveMessage.parameters.Count.ToString());
                            myLog.appendLogText(err.ToString());
                            myLog.appendLogText("##########################Exception END###########################");
                            return;
                        }
                        finally
                        {
                            
                        }    

                    //}
                                   
                }
            }

            public void parseRawData(byte[] rawData, int i = 1) { 
                int ii = 0;
                myLINReceiveMessage.debugArrayRawdata.Add(rawData);
                foreach (byte bb in rawData) {
                    myLINReceiveMessage.currentPCANPos = ii;
                    // here we will call PCANLINReceiveMessage.insertToReceiveBuffer() countinue from here 
                    myLINReceiveMessage.analyzePCANLINMessageByByte(rawData[ii]);
                    ii += 1;
                }
            }

 

            //private void parseRawData(byte[] rawData) { 
            //    // the process would be 
            //    // 1. check the raw data get the raw data type.
            //    // 1.1 if the raw data type is LIN forwarded data, collect it to LIN buffer array.
            //    // 1.2 if the raw data type is other, like the control message response, ignore it (or we could check it base on our last message later.)
            //    // check the LIN buffer array, if the array is full, trigger relevant var.
            //    int i;
            //    // while parsing the data, we need to know the very first thing, is if it is stx. to acheive this target, we need to do two things
            //    //1. if it's the very first message received and the very first byte is 0x02 then the very first byte is stx.
            //    //2. if it's not the very first message, then we need to track the message received before for it's length parameters.
            //    //after getting all the bytes of a complete LIN message ready. we need to judge the message and 
            //    //1. if it's LIN message, forwarded it to LIN message Manager.
            //    //2. if it's other type of message, ignore it.

            //    if (myLINReceiveMessage.tmpBuffer.Count > 0) {
            //        myLINReceiveMessage.firstFlag = false;
            //        myLINReceiveMessage.MessageCompleteFlag = false;
            //        myLINReceiveMessage.parameterFinishFlag = false;
            //    }

            //    if (myLINReceiveMessage.firstFlag || myLINReceiveMessage.MessageCompleteFlag) {

            //         if (rawData.Length < 2){
            //            myLINReceiveMessage.firstFlag = false;
            //            myLINReceiveMessage.MessageCompleteFlag = false;
            //            myLINReceiveMessage.parameterFinishFlag = false;
            //            myLINReceiveMessage.stx = rawData[0];
            //            myLINReceiveMessage.currentPraraPos = 0;
            //            myLINReceiveMessage.currentPCANPos = 1;
            //         }else{
            //            myLINReceiveMessage.firstFlag = false;
            //            myLINReceiveMessage.MessageCompleteFlag = false;
            //            myLINReceiveMessage.parameterFinishFlag = false;
            //            myLINReceiveMessage.stx = rawData[0];
            //            myLINReceiveMessage.sequenceCode = rawData[1];
            //            myLINReceiveMessage.AR = rawData[1] >> 7;
            //            myLINReceiveMessage.sequenceNumber = (rawData[1] & 0x70) >> 4;
            //            myLINReceiveMessage.frameLength = rawData[1] & 0xF;
            //            myLINReceiveMessage.currentPraraPos = 0;
            //            myLINReceiveMessage.currentPCANPos = 2;
            //         }

            //         if (rawData.Length < 3) {
            //             return;
            //         }
                   
            //        //myLINReceiveMessage.parameters[] = new byte[myLINReceiveMessage.frameLength];

            //        //we include the checksum byte into parameter list for saving the parse complexity.
            //         for (i = 0; i < rawData.Length - 1; i++)
            //         {
            //             myLINReceiveMessage.currentPCANPos = i + 1;
            //             if (i > 1) {
            //                 myLINReceiveMessage.currentPraraPos = i - 1;
            //                 myLINReceiveMessage.parameters.Insert(myLINReceiveMessage.currentPraraPos, rawData[i]);
                             
            //                 if (i > myLINReceiveMessage.frameLength + 2)
            //                 {
            //                     myLINReceiveMessage.parameterFinishFlag = true;
            //                     myLINReceiveMessage.MessageCompleteFlag = true;
            //                     myLINReceiveMessage.tmpBuffer.Insert(i - (myLINReceiveMessage.frameLength + 3), rawData[i]);
            //                     myLINReceiveMessage.currentPraraPos = myLINReceiveMessage.frameLength + 1;
            //                 }
            //                 else {
            //                     myLINReceiveMessage.parameters.Insert(myLINReceiveMessage.currentPraraPos, rawData[i]);
            //                 }
            //             }
            //         }

            //        //for (i = 2; i < myLINReceiveMessage.frameLength + 3; i++) {
            //        //    if (i > rawData.Length - 1){
            //        //        break; 
            //        //    }

            //        //    myLINReceiveMessage.parameters.Insert(myLINReceiveMessage.currentPraraPos, rawData[i]);
            //        //    //Console.WriteLine(rawData[i].ToString("x"));
            //        //    myLINReceiveMessage.currentPraraPos += 1;
            //        //}

            //        //if (myLINReceiveMessage.parameters.Count < myLINReceiveMessage.frameLength + 1)
            //        //{
            //        //    //
            //        //    myLINReceiveMessage.parameterFinishFlag = false;
            //        //}
            //        //else {
            //        //    myLINReceiveMessage.parameterFinishFlag = true;
            //        //    myLINReceiveMessage.MessageCompleteFlag = true;
            //        //    //myLog.appendLogText("complete PCANLIN msg received.");
            //        //    //myLINReceiveMessage.currentPraraPos = myLINReceiveMessage.frameLength + 1;
            //        //}
            //    }else{
            //        if (myLINReceiveMessage.tmpBuffer.Count > 0) {
            //            if (myLINReceiveMessage.tmpBuffer.Count < 2)
            //            {
            //                myLINReceiveMessage.firstFlag = false;
            //                myLINReceiveMessage.MessageCompleteFlag = false;
            //                myLINReceiveMessage.parameterFinishFlag = false;
            //                myLINReceiveMessage.stx = myLINReceiveMessage.tmpBuffer[0];// rawData[0];
            //                myLINReceiveMessage.currentPraraPos = 0;
            //                //myLINReceiveMessage.currentPCANPos = 1;
            //            }
            //            else
            //            {
            //                myLINReceiveMessage.firstFlag = false;
            //                myLINReceiveMessage.MessageCompleteFlag = false;
            //                myLINReceiveMessage.parameterFinishFlag = false;
            //                myLINReceiveMessage.stx = myLINReceiveMessage.tmpBuffer[0];
            //                myLINReceiveMessage.sequenceCode = myLINReceiveMessage.tmpBuffer[1];
            //                myLINReceiveMessage.AR = myLINReceiveMessage.tmpBuffer[1] >> 7;
            //                myLINReceiveMessage.sequenceNumber = (myLINReceiveMessage.tmpBuffer[1] & 0x70) >> 4;
            //                myLINReceiveMessage.frameLength = myLINReceiveMessage.tmpBuffer[1] & 0xF;
            //                myLINReceiveMessage.currentPraraPos = 0;
            //                //myLINReceiveMessage.currentPCANPos = 2;
            //            }
            //            if (myLINReceiveMessage.tmpBuffer.Count < 3) {
            //                return;
            //            }
            //            //continue from here
            //            for (i = 0; i < myLINReceiveMessage.tmpBuffer.Count - 1; i++)
            //            {
            //                //myLINReceiveMessage.currentPCANPos = i + 1;
            //                if (i > 1)
            //                {
            //                    myLINReceiveMessage.parameters.Insert(myLINReceiveMessage.currentPraraPos, myLINReceiveMessage.tmpBuffer[i]);
            //                    myLINReceiveMessage.currentPraraPos = i - 1;
            //                    if (i > myLINReceiveMessage.frameLength + 2)
            //                    {
            //                        myLINReceiveMessage.parameterFinishFlag = true;
            //                        myLINReceiveMessage.MessageCompleteFlag = true;
            //                        myLINReceiveMessage.tmpBuffer.Insert(i - (myLINReceiveMessage.frameLength + 3), rawData[i]);
            //                        myLINReceiveMessage.currentPraraPos = myLINReceiveMessage.frameLength + 1;
            //                    }
            //                    else
            //                    {
            //                        myLINReceiveMessage.parameters.Insert(myLINReceiveMessage.currentPraraPos, rawData[i]);
            //                    }
            //                }
            //            }
            //        }
            //        int tmpInt = myLINReceiveMessage.currentPraraPos;
            //        for (i = tmpInt; i < myLINReceiveMessage.frameLength + 1; i++)
            //        {
            //            if (i - tmpInt + 1 > rawData.Length - 1) {
            //                break;
            //            }
            //            myLINReceiveMessage.parameters.Insert(myLINReceiveMessage.currentPraraPos, rawData[i - tmpInt]);
            //            myLINReceiveMessage.currentPraraPos += 1;
            //        }
            //    }

            //    if (myLINReceiveMessage.currentPraraPos - 1 == myLINReceiveMessage.frameLength)
            //    {
            //        //myLog.appendLogText(myLINReceiveMessage.ToString());
            //        //this condition means we have collect a complete PCANLIN message. 
            //        //then we will judge this PCANLINMessage and forward it to LINManager if necessary.
            //        if (myLINReceiveMessage.AR == 1)
            //        {
            //            if (myLINReceiveMessage.sequenceNumber == 2)
            //            {
            //                //this condition means we have a LIN Message.
            //                //myLog.appendLogText(";" + DateTime.Now.ToString("mm:ss:fff")); 
            //                myLINReceiveMessage.msgType = PCANLINMSGType.LIN;
            //                //myLog.appendLogText("LIN message received.");
            //                //myLog.appendLogText(myLINReceiveMessage.ToString());
            //                //myLog.appendLogText(myLINReceiveMessage.ToString());
            //                myLINReceiveMessage.currentPraraPos = 0;
            //                //myLINReceiveMessage.firstFlag = true;
            //                myLINReceiveMessage.parameterFinishFlag = true;
            //                myLINReceiveMessage.MessageCompleteFlag = true;
            //                myLINReceiveMessage.parameters.Clear();
            //            }
            //        }
            //    }
            //}

            // there will be a event handler for the special vars. if the var meets some condition. handle the event.
            
       }




    }
}
